#include "stdafx.h"
#include "PacketQueue.h"

using namespace std;

CPacketQueue::CPacketQueue()
{
#if 1
	InitializeCriticalSection(&mQueueLock);
#endif
}


CPacketQueue::~CPacketQueue()
{
	Exit();
}

BOOL CPacketQueue::Initial()
{
	mQueueEvent = CreateEvent(0, TRUE, FALSE, 0);
	if (mQueueEvent == NULL) {
		return false;
	}
	mAlive = TRUE;

#if 0//	_MSC_PLATFORM_TOOLSET > 100
	mThread = new thread(ThreadFunc, this);
#else
	mThread = CreateThread(NULL, 0, ThreadFunc, this, 0, NULL);
#endif
	if (!mThread) {
		CloseHandle(mQueueEvent);
		return FALSE;
	}
	return TRUE;
}

BOOL CPacketQueue::Exit()
{
	mAlive = FALSE;
	CloseHandle(mQueueEvent);
	if (mThread) {
#if	0//_MSC_PLATFORM_TOOLSET > 100
		mThread->detach();
#else
		CloseHandle(mThread);
#endif
		mThread = NULL;
	}

	while (mPacketQueue.size()) {
		CETHFram*pkt = DeletePacket();
		delete pkt;
	}

	return TRUE;
}

BOOL CPacketQueue::AddPacket(CETHFram * Packet)
{
#if 0//_MSC_PLATFORM_TOOLSET > 100
	lock_guard<mutex> lk(mQueueLock);
#else
	EnterCriticalSection(&mQueueLock);
#endif

	mPacketQueue.push_back(Packet);

	if (::SetEvent(mQueueEvent) == FALSE) {
		printf("Error: SetEvent Failed!\n");
		LeaveCriticalSection(&mQueueLock);
		return FALSE;
	}
	LeaveCriticalSection(&mQueueLock);
	return TRUE;
}

CETHFram* CPacketQueue::DeletePacket()
{
#if 0//_MSC_PLATFORM_TOOLSET > 100
	lock_guard<mutex> lk(mQueueLock);
#else
	EnterCriticalSection(&mQueueLock);
#endif

	CETHFram* pkt = NULL;

	if (mPacketQueue.size()) {
		pkt = mPacketQueue.front();
		mPacketQueue.pop_front();
	}

	LeaveCriticalSection(&mQueueLock);
	return pkt;
}

DWORD CPacketQueue::ThreadFunc(LPVOID arg)
{
	CPacketQueue* mThis = reinterpret_cast<CPacketQueue*>(arg);
	if (!mThis)
		return 0;

	while (mThis->mAlive) {
		DWORD dwWaitResult = WaitForSingleObject(mThis->mQueueEvent, INFINITE);
		switch (dwWaitResult)
		{
			// Event object was signaled
		case WAIT_OBJECT_0:
		{
			CETHFram* pkt = mThis->DeletePacket();
			if (pkt){
				if (pkt->Process() < 1) {
					delete pkt;
				}
			}
			else {
				::ResetEvent(mThis->mQueueEvent);
			}
		}
		break;

		// An error occurred
		default:
			printf("CPacketQueue::ThreadFunc exit\n");
			return 0;
		}
	}

	return 0;
}
